using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.Modularity;
using Volo.Abp.Testing;
using Volo.Abp.Uow;

namespace Matrix.Configuration
{
    /// <summary>
    /// 应用层测试基类
    /// </summary>
    public abstract class MatrixConfigurationApplicationTestBase : AbpIntegratedTest<MatrixConfigurationApplicationTestModule>
    {
        protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
        {
            options.UseAutofac();
        }

        protected override void AfterAddApplication(IServiceCollection services)
        {
            services.AddAlwaysAllowAuthorization();
        }

        protected virtual T WithUnitOfWork<T>(Func<T> func)
        {
            return WithUnitOfWorkAsync(func).ConfigureAwait(false).GetAwaiter().GetResult();
        }

        protected virtual async Task<T> WithUnitOfWorkAsync<T>(Func<Task<T>> func)
        {
            using var scope = ServiceProvider.CreateScope();
            var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();

            using var uow = uowManager.Begin(new UnitOfWorkOptions { IsTransactional = true });
            try
            {
                var result = await func();
                await uow.CompleteAsync();
                return result;
            }
            catch
            {
                await uow.RollbackAsync();
                throw;
            }
        }

        protected virtual async Task WithUnitOfWorkAsync(Func<Task> action)
        {
            using var scope = ServiceProvider.CreateScope();
            var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();

            using var uow = uowManager.Begin(new UnitOfWorkOptions { IsTransactional = true });
            try
            {
                await action();
                await uow.CompleteAsync();
            }
            catch
            {
                await uow.RollbackAsync();
                throw;
            }
        }
    }
}